package com.blog.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.blog.common.Result;
import com.blog.dto.BlogDto;
import com.blog.mapper.BlogMapper;
import com.blog.pojo.Blog;
import com.blog.pojo.BlogTag;
import com.blog.pojo.Tag;
import com.blog.pojo.User;
import com.blog.service.*;
import com.blog.util.SnowFlakeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 博客相关
 */
@Slf4j
@RestController
@RequestMapping("/blog")
public class BlogController {
    @Autowired
    private BlogService blogService;

    @Autowired
    private BlogTagService blogTagService;

    @Autowired
    private TagService tagService;

    @Autowired
    private UserService userService;

    @Autowired
    private BlogMapper blogMapper;

    @Autowired
    private ThumbService thumbService;

    @Autowired
    private CollectionService collectionService;

    /**
     * 新增和修改博客：多表操作
     *
     * @param blogDto 数据传输Dto
     * @return Result<Long>
     */
    @PostMapping("/saveOrUpdate")
    public Result<Long> save(@RequestBody BlogDto blogDto) {
        String title = blogDto.getTitle();
        LambdaQueryWrapper<Blog> blogLambdaQueryWrapper = new LambdaQueryWrapper<>();
        blogLambdaQueryWrapper.eq(Blog::getTitle, title);
        //根据标题查找该博客，判断是否已经存在
        Blog blogServiceOne = blogService.getOne(blogLambdaQueryWrapper);
        if (blogServiceOne == null) {//数据库中无该博客，进行新增操作
            blogService.saveBlogWithTagIds(blogDto);
            //根据前端人员要求，新增成功后返回新增后的blogId
            Blog blogServiceOneThen = blogService.getOne(blogLambdaQueryWrapper);
            return Result.success(blogServiceOneThen.getBlogId());
        }
        //数据库中有数据
        blogService.updateBlogWithTagIds(blogDto);
        return Result.success(blogServiceOne.getBlogId());
    }

    /**
     * 保存草稿
     *
     * @param blog blog对象
     * @return Result<Long>
     */
    @PostMapping("/saveBlogDraft")
    public Result<Long> saveBlogDraft(@RequestBody Blog blog) {
        Long blogId = blog.getBlogId();
        if (blogId == null) {//无该博客
            Long defaultSnowFlakeId = SnowFlakeUtil.getDefaultSnowFlakeId();
            blog.setBlogId(defaultSnowFlakeId);
            blogService.save(blog);
            //返回新增后的id
            return Result.success(defaultSnowFlakeId);
        }
        blogService.updateById(blog);
        return Result.success(blogId);
    }

    /**
     * 查询当前用户的所有博客
     *
     * @param userId 用户id
     * @return Result<List<Blog>>
     */
    @GetMapping("/getUserAllBlog")
    public Result<List<Blog>> getUserAllBlog(@RequestParam Long userId) {
        LambdaQueryWrapper<Blog> blogLambdaQueryWrapper = new LambdaQueryWrapper<>();
        blogLambdaQueryWrapper.eq(Blog::getUserId, userId);
        List<Blog> blogList = blogService.list(blogLambdaQueryWrapper);
        //将博客的内容置空，加快传输速度
        for (Blog blog : blogList) {
            blog.setContent(null);
        }
        return Result.success(blogList);
    }

    /**
     * 展示最近更新的10条博客
     * @return Result<List<Blog>>
     */
    @GetMapping("/getLatestBlog")
    private Result<List<Blog>> getLatestBlog(){
        LambdaQueryWrapper<Blog> blogLambdaQueryWrapper = new LambdaQueryWrapper<>();
        blogLambdaQueryWrapper.orderByDesc(Blog::getCreateTime);
        List<Blog> blogList = blogService.list(blogLambdaQueryWrapper);
        for (Blog blog : blogList) {
            blog.setContent(null);
        }
        return Result.success(blogList.subList(0,10));
    }

    /**
     * 博客详情信息。
     *
     * @param blogId 博客id
     * @return Result<BlogDto>
     */
    @GetMapping("/getTheBlog")
    public Result<BlogDto> getTheBlog(@RequestParam Long blogId) {
        //获取博客基本内容
        Blog blogServiceById = blogService.getById(blogId);
        //---给该博客的点赞数赋值
        blogServiceById.setThumbsCount(thumbService.countTheBlogThumbs(blogId));
        //---给该博客的收藏量数赋值
        blogServiceById.setCollectionCount(collectionService.countTheBlogCollection(blogId));
        //根据前端要求，存入数据库
        blogService.updateById(blogServiceById);
        //获取该博客的所有标签
        LambdaQueryWrapper<BlogTag> blogTagLambdaQueryWrapper = new LambdaQueryWrapper<>();
        blogTagLambdaQueryWrapper.eq(BlogTag::getBlogId, blogId);
        List<BlogTag> blogTagList = blogTagService.list(blogTagLambdaQueryWrapper);
        //1.给Dto赋值
        BlogDto blogDto = new BlogDto();
        //1.1 Blog对象拷贝给BlogDto
        BeanUtils.copyProperties(blogServiceById, blogDto);
        //1.2 赋值给tag数组
        List<Tag> tagList = new ArrayList<>();
        for (BlogTag blogTag : blogTagList) {
            tagList.add(tagService.getById(blogTag.getBlogTagId()));
        }
        //浏览量+1
        blogServiceById.setVisitCount(blogServiceById.getVisitCount() + 1);
        blogService.updateById(blogServiceById);

        blogDto.setTagList2(tagList);
        return Result.success(blogDto);
    }

    /**
     * 返回博客的作者信息
     *
     * @param blogId 博客id
     * @return Result<User>
     */
    @GetMapping("/getAuthorByBlogId")
    private Result<User> getAuthorByBlogId(@RequestParam Long blogId) {
        Blog blogServiceById = blogService.getById(blogId);
        User userServiceByBlogId = userService.getById(blogServiceById.getUserId());
        if (userServiceByBlogId!=null) {
            //敏感信息置null
            userServiceByBlogId.setUserPassword(null);
            return Result.success(userServiceByBlogId);
        }
        return Result.error("没有查询到该作者的博客信息。");
    }

    /**
     * 逻辑删除blog：注，逻辑删除后再恢复blog标签将会丢失全部标签，前台请提示用户！
     * 逻辑删除blog是假删除，但blog和tag的关联表没有isDelete属性，因此是真删除！
     *
     * @param blogId 博客id
     * @return Result<String>
     */
    @DeleteMapping("/delete")
    public Result<String> delete(@RequestParam Long blogId) {
        return Result.success(blogService.updateDeleteStatus(blogId));
    }

    /**
     * 博客审核：审核后还可以退审（打回）
     *
     * @param blogId 博客id
     * @return Result<String>
     */
    @GetMapping("/blogAudit1")
    public Result<String> blogAudit1(Long blogId) {
        Blog blogServiceById = blogService.getById(blogId);
        Integer blogStatus = blogServiceById.getBlogStatus();
        if (blogStatus == 1) {   //已发布待审核状态
            blogServiceById.setBlogStatus(2);
            blogService.updateById(blogServiceById);
            return Result.success("博客审核通过！");
        } else if (blogStatus == 0) { //草稿状态
            return Result.error("博客作者还未发布该博客（草稿状态）！无法审核。");
        } else {  //已审核状态
            blogServiceById.setBlogStatus(1);
            blogService.updateById(blogServiceById);
            return Result.success("打回博客成功！");
        }
    }

    /**
     * 博客审核：审核后还可以退审（打回）
     *
     * @param blogId 博客id
     * @param blogStatus 博客状态
     * @return Result<String>
     */
    @GetMapping("/blogAudit")
    public Result<String> blogAudit(Long blogId,Integer blogStatus) {
        Blog blogServiceById = blogService.getById(blogId);
        blogServiceById.setBlogStatus(blogStatus);
        blogService.updateById(blogServiceById);
        return Result.success("审核成功！");
    }

    /**
     * 博客分页查询
     * @param page 当前页
     * @param pageSize 当前页大小
     * @return Result<Page>
     */
    @GetMapping("/page")
    public Result<Page> page(int page,int pageSize){
        return Result.success(blogService.page(page,pageSize));
    }

    /**
     * 博客全局索引（Mysql实现，另外还在ES Controller中通过ES实现）
     * @param titleOrDescriptionOrContent blog标题或描述或内容
     * @return Result<List>
     */
    @GetMapping("/search")
    public Result<List> search(String titleOrDescriptionOrContent) {
        List<Blog> blogList = blogService.list();
        List<Long> blogIdList = new ArrayList<>();
        for (Blog blog : blogList) {
            //将全局搜索包含的3列数据整合到一个String中进行条件查找
            String searchString = blog.getTitle() + blog.getDescription() + blog.getContent();
            if (searchString.contains(titleOrDescriptionOrContent)){//如果包含搜索的字符串
                blogIdList.add(blog.getBlogId());
            }
        }
        List<Blog> selectBatchIds = blogMapper.selectBatchIds(blogIdList);
        return Result.success(selectBatchIds);
    }

    /**
     * 返回该分类下的所有博客
     * @param typeId 类型id
     * @return Result<List<Blog>>
     */
    @GetMapping("/listByTypeId")
    public Result<List<Blog>> listByTypeId(Long typeId){
        LambdaQueryWrapper<Blog> blogLambdaQueryWrapper = new LambdaQueryWrapper<>();
        blogLambdaQueryWrapper.eq(Blog::getTypeId,typeId);
        List<Blog> list = blogService.list(blogLambdaQueryWrapper);
        for (Blog blog : list) {
            blog.setContent(null);
        }
        return Result.success(list);
    }

    /**
     * 待审核状态的所有博客
     * @return Result<List<Blog>>
     */
    @GetMapping("/listByStatus1")
    private Result<List<Blog>> listByStatus1(){
        LambdaQueryWrapper<Blog> blogLambdaQueryWrapper = new LambdaQueryWrapper<>();
        blogLambdaQueryWrapper.eq(Blog::getBlogStatus,1);
        List<Blog> blogList = blogService.list(blogLambdaQueryWrapper);
        for (Blog blog : blogList) {
            blog.setContent(null);
        }
        return Result.success(blogList);
    }

}
